#include "ParticleSystem.h"

#include <windows.h>
#include <time.h>
#include "graphics.h"
#include "vec3.h"

#include "GL/gl.h"
#include "GL/glut.h"

ParticleSystem sys;
cudaEvent_t start, stop;

void renderScene();
static void Keyboard( unsigned char key, int x, int y );
static void Redraw ();
static void Idle();

int main(int argc, char *argv[])
{
    srand(time(NULL));

    cudaEventCreate(&start);
    cudaEventCreate(&stop);

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGB);
    glutInitWindowSize(800,600);
    glutCreateWindow("Projeto Final");
    glutDisplayFunc(Redraw);
    glutKeyboardFunc(Keyboard);
    glutIdleFunc(Idle);

    sys.initCudaArrays();

    glutMainLoop();

    return 0;
}

static void Keyboard( unsigned char key, int x, int y )
{
    switch( key )
    {
    case 'q':
	    exit(0);
	    break;
    case 'p':
        if( sys.numParticles < NUM_PARTICLES )
        {
            sys.numParticles++;
        }
    }
}

static void Redraw ()
{
#ifdef RENDER
    Gra::BeginDrawing();
    Gra::LoadCamera(
      60.0f,               // angulo de abertura da camera
      0.0f, 10.0f, 30.0f,  // posicao da camera
      0.0f, 0.0f, 0.0f,    // centro da cena
      0.0f, 1.0f, 0.0f     // vetor "up"
    );

    renderScene();

    Gra::EndDrawing();
#endif
}

static void Idle()
{
    float timeStep = FIXED_TIME_STEP; //segundos
    float timeElapsed;
    
    static int numOfSteps = 0;
    
    cudaEventRecord(start, 0);
    sys.update(timeStep);
#ifdef RENDER
    Redraw();
#endif
    cudaEventRecord(stop, 0);
    cudaEventSynchronize(stop);

    if( sys.numParticles < NUM_PARTICLES )
        sys.numParticles++;

    numOfSteps++;

    if( numOfSteps > 500 )
    {
        numOfSteps = 0;
        cudaEventElapsedTime(&timeElapsed, start, stop);
        printf( "Time for update: %f ms\n", timeElapsed );
    }
}

void renderScene()
{
#ifdef RENDER
    int numParticles = sys.numParticles;
    for( int i=0; i<numParticles; ++i )
    {
        Gra::DrawSphere( sys.pRadius[i],
            sys.pPosition[i].x,
            sys.pPosition[i].y,
            sys.pPosition[i].z,
            sys.pColor[i].x,
            sys.pColor[i].y,
            sys.pColor[i].z );
    }

    Gra::DrawPlane(0,0,0,0,1,0,(float)BOX_DIM/2.0f,0.3,1.0,0.3);
#endif
}